/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package proyectoso;

import java.util.concurrent.Semaphore;

/**
 *
 * @author Christian
 */
public class Child implements Runnable {
    int isla;
    Bote b;
    int persona;
    Arena ar;
    int childrenintheislandM;
    int adultsintheislandM;
    int adultsintheislandO;
    int childrenintheislandO;
    Semaphore sem;
    boolean flagbote;
    boolean passenger;
    Avisar av;
    
    Child(int is, Bote b1, Arena a, Semaphore s, Avisar avisar){
        this.isla=is;
        this.b=b1;
        this.persona=0;
        this.ar=a;
        this.sem=s;
        //false cuando no esta en el bote y true para cuando esta en el bote y puede remar
        this.flagbote=false;
        this.passenger=false;
        this.av=avisar;
    }
    public void run(){
        this.ar.Escribir(isla, persona);
        if(ar.GetChildren(isla)>=2)
            this.ar.NotifyAll();
        if(ar.GetChildren(isla)==1)
            this.ar.Wait();
        while(RevisarCondiciones()){
            if (isla==0){
                if(ar.GetChildren(isla)==1){
                    synchronized(ar){
                        try{
                            if(this.ar.GetAdultos(isla)>0)
                                ar.wait();
                        }
                        catch(Exception e){
                            
                        }
                    }
                }
                if(ar.GetChildren(isla)>=2){
                    this.BuscarBote();
                    this.Viajan2();
                }
            }
            else{
                this.BuscarBote();
                this.ViajoDeVuelta();
            }
        }
        if(ar.GetChildren(isla)>=2){
            if(ar.GetChildren(isla)%2==0){
                this.Viajan2();
                if(childrenintheislandO==0)
                    av.DarAviso();
            }
            else{
                this.Viaja1();
                if(childrenintheislandO==0)
                    av.DarAviso();
            }
        }
        else{
            this.Viaja1();
            if(childrenintheislandO==0)
                av.DarAviso();
        }
    }
    public synchronized void ViajoDeVuelta(){
        if(ar.GetChildren(isla)==childrenintheislandM)
            this.Viaja1();
    }
    public void BuscarBote(){
        if(this.isla==0){
            synchronized(b){
                try{
                    if(b.isla==1)
                        b.wait();
                }
                catch(Exception e){
            
                }
            }
        }
        else{
            synchronized(b){
                try{
                    if(b.isla==0)
                        b.wait();
                }
                catch(Exception e){
            
                }
            }
        }
    }
    public void Viaja1(){
        try{
            sem.acquire(2);
            b.TomarBoteChild(this);
            ar.Borrar(isla, persona);
            this.Leer();
            b.ViajarChild(this);
            sem.release(2);
        }
        catch (InterruptedException e){
        
        }
    }
    public void Viajan2(){
        try{
            sem.acquire(1);
            b.TomarBoteChild2(this);
            synchronized(b){
                try{
                    if(b.GetChildren()==1)
                    b.wait();
                }
                catch(Exception e){
                
                }
            }
            synchronized (b){
                if (b.GetChildren()==2)
                    b.notify();
                    ar.Borrar(isla, persona);
                }
                this.Leer();
                b.ViajarChild(this);
                sem.release(1);
        }
        catch(Exception e){
        
        }
    }
    public void Leer(){
        if (isla==0){
            childrenintheislandO=ar.GetChildren(isla);
            adultsintheislandO=ar.GetAdultos(isla);
        }
        else{
            childrenintheislandM=ar.GetChildren(isla);
            adultsintheislandM=ar.GetAdultos(isla);
        }
    }
    public boolean RevisarCondiciones(){
        this.Leer();
        if (adultsintheislandO>0)
            return true;
        else
            return false;
    }
    public boolean GetFlag(){
        return flagbote;
    }
    public void SetFlag(boolean f){
        this.flagbote=f;
    }
    public int GetIsla(){
        return isla;
    }
    public void SetIsla(int is){
        this.isla=is;
    }
    public int GetPerson(){
        return persona;
    }
}
